param ( $CmdletName = "", $ProjectName = "", $ServiceUri = "http://www.snapins.com/api/cmdlet.asmx")
# /////////////////////////////
# ///// Usage function
# /////////////////////////////
if (! $CmdletName  -or ! $ProjectName ) 
{
    write-Host "Missing Command Name and/or ProjectName"
    Write-Host "Usage"
    Write-Host "Get-FunctionTemplate.ps1 CmdletName ProjectName"
    Write-Host "Example: Get-FunctionTemplate.ps1 Get-MailBox Exchange12 `"http://www.snapins.com/api/cmdlet.asmx`""
    return 
}

# ///// Split the comment lines into 76 character long and add "///"
function SplitDescString ($str, $spacesValue)
{
    $b = $str.Trim("`n `r") | %{[Regex]::Split($_,'(.{0,76}(?:\s|$))')}|%{if($_){$spacesValue + " $_`r`n"}}
    $length = $b.length
    if (($length -gt 0) -and ($b.GetType().Name -ne "string"))
    {
        $b[$length - 1] = $b[$length - 1].ToString().TrimEnd("`n `r")
    }
    elseif ($b -ne $null)
    {
        $b = $b.ToString().TrimEnd("`n `r")
    }
    else
    {
        $b = $spacesValue
    }

    $b
}


function FirstLetterToUpper ($a)
{
    $a[0].ToString().ToUpper() + $a.Substring(1, $a.Length - 1)
}

$verbMapping = @{
    "Add" = "VerbsCommon.Add";
    "Clear" = "VerbsCommon.Clear";
    "Copy" = "VerbsCommon.Copy";
    "Get" = "VerbsCommon.Get";
    "Lock" = "VerbsCommon.Lock";
    "Move" = "VerbsCommon.Move";
    "New" = "VerbsCommon.New";
    "Remove" = "VerbsCommon.Remove";
    "Rename" = "VerbsCommon.Rename";
    "Set" = "VerbsCommon.Set";
    "Join" = "VerbsCommon.Join";
    "Split" = "VerbsCommon.Split";
    "Select" = "VerbsCommon.Select";
    "Unlock" = "VerbsCommon.Unlock";
    "Backup" = "VerbsData.Backup";
    "Checkpoint" = "VerbsData.Checkpoint";
    "Compare" = "VerbsData.Compare";
    "Convert" = "VerbsData.Convert";
    "ConvertFrom" = "VerbsData.ConvertFrom";
    "ConvertTo" = "VerbsData.ConvertTo";
    "Export" = "VerbsData.Export";
    "Import" = "VerbsData.Import";
    "Initialize" = "VerbsData.Initialize";
    "Limit" = "VerbsData.Limit";
    "Merge" = "VerbsData.Merge";
    "Restore" = "VerbsData.Restore";
    "Update" = "VerbsData.Update";
    "Mount" = "VerbsData.Mount";
    "Dismount" = "VerbsData.Dismount";
    "Out" = "VerbsData.Out";
    "Disable" = "VerbsLifecycle.Disable";
    "Enable" = "VerbsLifecycle.Enable";
    "Install" = "VerbsLifecycle.Install";
    "Restart" = "VerbsLifecycle.Restart";
    "Resume" = "VerbsLifecycle.Resume";
    "Start" = "VerbsLifecycle.Start";
    "Stop" = "VerbsLifecycle.Stop";
    "Suspend" = "VerbsLifecycle.Suspend";
    "Uninstall" = "VerbsLifecycle.Uninstall";
    "Debug" = "VerbsDiagnostic.Debug";
    "Measure" = "VerbsDiagnostic.Measure";
    "Ping" = "VerbsDiagnostic.Ping";
    "Resolve" = "VerbsDiagnostic.Resolve";
    "Test" = "VerbsDiagnostic.Test";
    "Trace" = "VerbsDiagnostic.Trace";
    "Send" = "VerbsCommunications.Send";
    "Receive" = "VerbsCommunications.Receive";
    "Connect" = "VerbsCommunications.Connect";
    "Disconnect" = "VerbsCommunications.Disconnect";
    "Write" = "VerbsCommunications.Write";
    "Read" = "VerbsCommunications.Read";
    "Grant" = "VerbsSecurity.Grant";
    "Revoke" = "VerbsSecurity.Revoke";
    "Block" = "VerbsSecurity.Block";
    "Unblock" = "VerbsSecurity.Unblock";
    "Use" = "VerbsOther.Use";
}

# check to see if the Cmdlet record already exists.
$cmdletRecord = Get-PsSpecCmdlet -Service $ServiceUri -Name $CmdletName -ProjectName $ProjectName -EA SilentlyContinue

### We create the Cmdlet record here if one does not exit.
if ($cmdletRecord)
{
    #$verb is Cmdlet verb   
    $cmdletVerb = $cmdletRecord.Verb
    $verb = $verbMapping[$cmdletVerb]

    #$noun is Cmdlet noun
    $noun = $cmdletRecord.Noun

    #Check for ShouldProcess.
    if ($cmdletRecord.SupportsShouldProcess)
    {
        #Write-Host SupportShouldProcess is true
        $ShouldProcess = $cmdletRecord.SupportsShouldProcess.ToString().ToLower()
        $SupportShouldProcess = ",`r`n             SupportsShouldProcess=`${ShouldProcess}"
    }
    else
    {
        $SupportShouldProcess = $null
    }
    
    if ($cmdletRecord.LongDescription -ne $null)
    {
        $description = $cmdletRecord.LongDescription  
        $description = SplitDescString $description "   #"
    }
    else
    {
        $description = $null
    }

    $projectName = FirstLetterToUpper $projectName 

    $cmdletHeading=@"
<#
   .NAME
   	${CmdletVerb}-${noun}
   .SUMMARY
		$Description
#>
function ${cmdletverb}-$noun {
	[CmdletBinding(${SupportsShouldProcess})]
	param(
"@

	$cmdletHeading

    $Entries = @(Get-PsSpecCmdletParameterSetEntry -Service $ServiceUri -CmdletName $CmdletName -ProjectName $projectName | Sort ParameterName)
    $Params = @(Get-PsSpecCmdletParameter -Service $ServiceUri -CmdletName $CmdletName -ProjectName $projectName)

    $ParameterBody = New-Object "System.Collections.ObjectModel.Collection``1[[System.String]]"

    foreach ($param in $Params) 
    {
            $FirstParamEntry = $null
            $heading = New-Object "System.Collections.ObjectModel.Collection``1[[System.String]]"

            foreach ($entry in $Entries) 
                    { 
                            $Comma = $null
                            if ( $entry.ParameterName -eq ($param.Name) )
                                    {
                                            if ($entry.Mandatory)
                                                    {
                                                            $Mandatory = $entry.Mandatory.ToString().ToLower()
                                                            $Mandatory = "Mandatory = `$${Mandatory}"
                                                            $Comma = ",`r`n "
                                                    }
                                            else
                                                    {
                                                            $Mandatory = $null
                                                    }

                                            if ($entry.Position -ne $null)
                                                    {
                                                            $PositionValue = $entry.Position.ToString()
                                                            $Position ="${Comma}Position = ${PositionValue}"
                                                            $Comma = ",`r`n "
                                                    }
                                            else
                                                    {
                                                            $Position = $null
                                                    }

                                            if ($entry.ValueFromPipeline)
                                                    {

                                                            $ValueFromPipeline = $entry.ValueFromPipeline.ToString().ToLower()
                                                            $ValueFromPipeline = "${Comma}ValueFromPipeline = `$${ValueFromPipeline}"
                                                            $Comma = ",`r`n "

                                                    }
                                            else
                                                    {
                                                            $ValueFromPipeline = $null
                                                    }

                                            if ($entry.ValueFromPipelineByPropertyName)
                                                    {
                                                            $ValueFromPipelineByPropertyName = $entry.ValueFromPipelineByPropertyName.ToString().ToLower()
                                                            $ValueFromPipelineByPropertyName = "${Comma}ValueFromPipelineByPropertyName = `$${ValueFromPipelineByPropertyName}"
                                                            $Comma = ",`r`n "
                                                    }
                                            else
                                                    {
                                                            $ValueFromPipelineByPropertyName = $null
                                                    }

                                            if ($entry.ValueFromRemainingArguments)
                                                    {
                                                            $ValueFromRemainingArguments = $entry.ValueFromRemainingArguments.ToString().ToLower()
                                                            $ValueFromRemainingArguments = "${Comma}ValueFromRemainingArguments = `$${ValueFromRemainingArguments}"
                                                            $Comma = ",`r`n "
                                                    }
                                            else
                                                    {
                                                            $ValueFromRemainingArguments = $null
                                                    }


                                            if ($entry.ParameterSetName -ne $null)
                                                    {					
                                                            $SetName = $entry.ParameterSetName		
                                                            $ParameterSetName = "${Comma}ParameterSetName = `"${SetName}`""
                                                            $Comma = ",`r`n "
                                                    }
                                            else
                                                    {
                                                             $ParameterSetName = $null
                                                    }
                                            if ($comma)
                                                    {

                                                            $attribute = "$FirstParamEntry`t[Parameter(${Mandatory}${Position}${ValueFromPipeline}${ValueFromPipelineByPropertyName}${ValueFromRemainingArguments}${ParameterSetName})]" 
                                                            $FirstParamEntry = "`r`n"
                                                    }
                                            else
                                                    {
                                                            $attribute = "$FirstParamEntry`t[Parameter()]"
                                                            $FirstParamEntry = "`r`n"
                                                    }
                                            $heading.Add($attribute)						
                                    }
                    }

            $ParamType = $param.Type.ToString().Replace("System.","").Replace("Management.Automation.","")
            if ($param.Description -ne $null)
              {
                    $ParamDefinition = SplitDescString $param.Description "`t#"
              }
            $ParamName = FirstLetterToUpper $param.Name.ToString()
            $LowerCaseParamName = $ParamName.ToLower()
            $ParameterText=@"
${heading}
`t[${ParamType}]`$${ParamName}
"@
	$ParameterText
	}

    $CmdletEnd=@"
	) # end param

	begin {
	}

	process {
	}

	end {
	}
} # end function
"@

    $CmdletEnd
}
else
{
	Write-Host This cmdlet does not exist
}